/**
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yinglan.shadowimageview;

import com.yinglan.shadowimageview.util.Constants;
import com.yinglan.shadowimageview.util.Utils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Image;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.agp.window.service.DisplayAttributes;
import ohos.app.Context;

/**
 * RoundImageView
 *
 * @author name
 * @since 2021-03-31
 */
public class RoundImageView extends Image implements Component.DrawTask {
    private Paint paint; // 绘制圆角
    private int roundWidth = 0;
    private int roundHeight = 0;
    private int shadowRound = 0;

    /** RoundImageView
     *
     * @param context
     */
    public RoundImageView(Context context) {
        this(context, null);
    }

    /** RoundImageView
     *
     * @param context
     * @param attrs
     */
    public RoundImageView(Context context, AttrSet attrs) {
        this(context, attrs, "0");
    }

    /** RoundImageView
     *
     * @param context
     * @param attrs
     * @param defStyle
     */
    public RoundImageView(Context context, AttrSet attrs, String defStyle) {
        super(context, attrs, defStyle);
        init(context,attrs);
        addDrawTask(this::onDraw);
    }

    private void init(Context context,AttrSet attrs) {
        Utils utils = Utils.getInstance();
        int imageresource = Constants.IMAGERESOURCE;
        if (attrs != null) {
            // 获取xml中设置的自定义属性值
            shadowRound = utils.getAttrIntValue(attrs,"shadowRound",shadowRound);
            imageresource = utils.getAttrIntValue(attrs,"shadowSrc",Constants.IMAGERESOURCE);
            imageresource = ResourceTable.Media_lotus;
        } else {
            DisplayAttributes displayAttributes = utils.getScreenPiex(context);
            shadowRound = (int)(shadowRound * displayAttributes.scalDensity);
            imageresource = Constants.IMAGERESOURCE;
        }

        paint = new Paint();
        paint.setColor(Color.WHITE);
        paint.setAntiAlias(true);
        setScaleMode(ScaleMode.STRETCH);

        if (imageresource == Constants.IMAGERESOURCE) {
            this.setPixelMap(ResourceTable.Color_transparent);
        } else {
            this.setPixelMap(imageresource);
        }
    }

    /** setRound
     *
     * @param round
     */
    public void setRound(int round) {
        int rad = round;
        if (round > getWidth() / Constants.TWO || round > getHeight() / Constants.TWO) {
            if (getWidth() > getHeight()) {
                rad = getHeight() / Constants.TWO;
            } else {
                rad = getWidth() / Constants.TWO;
            }
        }
        this.roundHeight = rad;
        this.roundWidth = rad;
        invalidate();
    }

    /** setImageResource
     *
     * @param resId
     */
    public void setImageResource(int resId) {
        setPixelMap(resId);
        invalidate();
    }

    /** setImageRadius
     *
     * @param radius
     */
    public void setImageRadius(int radius) {
        int rad = radius;
        if (radius > getWidth() / Constants.TWO || radius > getHeight() / Constants.TWO) {
            if (getWidth() > getHeight()) {
                rad = getHeight() / Constants.TWO;
            } else {
                rad = getWidth() / Constants.TWO;
            }
        }
        shadowRound = rad;
        setRound(shadowRound);
        invalidate();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        // 绘制圆角
        drawLiftUp(canvas);
        drawLiftDown(canvas);
        drawRightUp(canvas);
        drawRightDown(canvas);
    }

    private void drawLiftUp(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, roundHeight);
        path.lineTo(0, 0);
        path.lineTo(roundWidth, 0);
        path.arcTo(new RectFloat(0, 0, roundWidth * Constants.TWO,
                roundHeight * Constants.TWO), Constants.NEGNINETY, Constants.NEGNINETY);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawLiftDown(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, getHeight() - roundHeight);
        path.lineTo(0, getHeight());
        path.lineTo(roundWidth, getHeight());
        path.arcTo(new RectFloat(0, getHeight() - roundHeight * Constants.TWO,
                roundWidth * Constants.TWO, getHeight()), Constants.NINETY, Constants.NINETY);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightDown(Canvas canvas) {
        Path path = new Path();
        path.moveTo(getWidth() - roundWidth, getHeight());
        path.lineTo(getWidth(), getHeight());
        path.lineTo(getWidth(), getHeight() - roundHeight);
        path.arcTo(new RectFloat(getWidth() - roundWidth * Constants.TWO, getHeight()
                - roundHeight * Constants.TWO, getWidth(), getHeight()), Constants.NEGZERO, Constants.NINETY);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightUp(Canvas canvas) {
        Path path = new Path();
        path.moveTo(getWidth(), roundHeight);
        path.lineTo(getWidth(), 0);
        path.lineTo(getWidth() - roundWidth, 0);
        path.arcTo(new RectFloat(getWidth() - roundWidth * Constants.TWO,
                0, getWidth(), 0 + roundHeight * Constants.TWO), Constants.NEGNINETY, Constants.NINETY);
        path.close();
        canvas.drawPath(path, paint);
    }
}
